﻿#include "SLT_tcpSenderImpl.h"
#include "SLT_tcpServerImpl.h"

#define  _CACTCPPROT_LOG_DEBUG(_format,...)  SLT_LOG(1,SLT_DEBUG,"[tcpserver]" _format, ##__VA_ARGS__)
#define  _CACTCPPROT_LOG_INFO(_format,...)  SLT_LOG(1,SLT_INFO,"[tcpserver]" _format, ##__VA_ARGS__)
#define  _CACTCPPROT_LOG_ERR(_format,...)  SLT_LOG(1,SLT_ERROR,"[tcpserver]" _format, ##__VA_ARGS__)

SLT_tcpServerFrameImpl* SLT_tcpServerFrameImpl::getInst()
{
	static std::once_flag   g_onceFlag;
	static SLT_tcpServerFrameImpl* g_server_20220719 = nullptr;
	if (nullptr == g_server_20220719) {
		std::call_once(g_onceFlag,[](){
			g_server_20220719 = new SLT_tcpServerFrameImpl;
			SLF_addSession(SLF_SessionBasePtr(g_server_20220719));
		});
	}
	return g_server_20220719;
}
SLT_tcpSenderProtocolImplSptr SLT_tcpServerFrameImpl::newSender()
{
	SLT_tcpSenderProtocolImplSptr sender = std::make_shared< SLT_tcpSenderProtocolImpl>(this);
	sender->m_id = m_senderidBase++;
	return sender;
}
SLT_TCPSenderPtr  SLT_tcpServerFrameImpl::getSender(SLTcpClientPtr &_client,const std::string& _rip, uint16_t _rport, bool reuse)
{
	char strkey[128];
	snprintf(strkey,sizeof(strkey), "%s_%u", _rip.c_str(), _rport);

	SLT_autoRWLock arw(&m_senderMapRwlock,SLT_autoRWLock::lock_write);
	auto sendIter = m_senderMap.find(strkey);
	if (sendIter == m_senderMap.end()) {
		SLT_tcpSenderProtocolImplSptr sender = newSender();
		m_senderMap.insert(make_pair(strkey, sender));

		sender->connect(_client,_rip, _rport);
		return sender->getSenderApt(); //自动增加了sender 的引用计数
	}
	return sendIter->second->getSenderApt();
}

SLT_TCPSenderPtr  SLT_tcpServerFrameImpl::getProxySender(SLTcpClientPtr &_client,const std::string& _rip, uint16_t _rport,
		                int _prefix1, int _prefix2, int _prefix3,int _devno,int _subno,const std::string &_svrid,int _encrypt,int _timeout_ms)
{
	//代理sender不能复用
	//代理转发sender，tcp连接后，先发送代理协议头。后面就是数据流.
	//放到map中，只是为了触发重连

	uint32_t   senderid = m_senderidBase++;  //保证sender唯一
	char strkey[64];
	snprintf(strkey,sizeof(strkey), "%u_proxysender", senderid);

	SLT_autoRWLock arw(&m_senderMapRwlock, SLT_autoRWLock::lock_write);
	auto sendIter = m_senderMap.find(strkey);
	if (sendIter != m_senderMap.end()) {
		_CACTCPPROT_LOG_DEBUG("tcp server create proxy sender error:%s", strkey);
		return {};
	}
		
	SLT_TCPProxyTransSenderImplSptr sender = std::make_shared< SLT_TCPProxyTransSenderImpl>(this);
	sender->m_id = senderid;
	m_senderMap.insert(make_pair(strkey, sender));

	sender->setProxyInfo(_prefix1,_prefix2,_prefix3,_devno,_subno,_svrid,_encrypt,_timeout_ms);
	sender->connect(_client,_rip, _rport);

	_CACTCPPROT_LOG_DEBUG("tcp server create sender:%s", strkey);
	return sender->getSenderApt(); //自动增加了sender 的引用计数
	
}

int SLT_tcpServerFrameImpl::tryDelSender(const std::string& _senderkey)
{
	SLT_autoRWLock arw(&m_senderMapRwlock, SLT_autoRWLock::lock_write);
	auto sendIter = m_senderMap.find(_senderkey);
	if (sendIter == m_senderMap.end()) {
		return 0;
	}

	if (0 == sendIter->second->m_usernum) {
		_CACTCPPROT_LOG_DEBUG("tcp server del sender:%s", _senderkey.c_str());
		m_senderMap.erase(_senderkey);
		return 0;
	}
	return -1;	
}
void SLT_tcpServerFrameImpl::OnStart()
{
	setTimer(1,1000,false);
}
void SLT_tcpServerFrameImpl::OnTimer(uint32_t timerID, int _intervalMs, bool periodic)
{
	setTimer(1,1000,false);
	std::map<std::string, SLT_tcpSenderProtocolImplSptr> tempMap;
	{
		SLT_autoRWLock arw(&m_senderMapRwlock, SLT_autoRWLock::lock_read);
		tempMap = m_senderMap;
	}
	
	for(auto &sender : tempMap){
		sender.second->checkState();
	}
}